# This file defines the class of ramp meter.

class RampMeter(object):
    """
    LINK_GROUP: (int) the link group index of the section that the ramp meter is conneted to
    IDX: (int) the index of the on-ramp
    DC: (VISSIM Object) the VISSIM object of data collection on the ramp
    SC: (VISSIM Object) the VISSIM object of the signal controller associated with the ramp meter
    QC: (VISSIM Object) the VISSIM object of the queue counter associated with the ramp meter
    Qcap: (double) reference queue capacity for the ramp
    RHO: (double) reference density of the connected highway section
    redTime: expected red light time 
    greenTime: expected green light time
    RedTimer: (double) timer for the red light
    GreenTimer: (double) timer for the greent light
    """
    def __init__(self, LINK_GROUP, IDX, DC, SC, QC, Qcap, RHO):
        self.LINK_GROUP = LINK_GROUP
        self.IDX = IDX
        self.DC = DC
        self.SC = SC
        self.QC = QC
        self.SG = self.SC.SGs.ItemByKey(1)
        self.Qcap = Qcap
        self.RHO = RHO
        self.redTime = 3.0
        self.RedTimer = 0.0
        self.greenTime = 2.0
        self.GreenTimer = 0.0


    def get_state(self):
        '''
        get current state of the signal light of the ramp meter
        '''
        return self.SG.AttValue('SigState')
    
    def red_increment(self, sim_step):
        '''
        increment the red timer
        sim_step: (double) time period of simulation step in seconds
        '''
        self.RedTimer += sim_step

    def change2green(self):
        '''
        change the light to green
        '''
        self.SG.SetAttValue('SigState', 3)
        self.RedTimer = 0

    def green_increment(self, sim_step):
        '''
        increment the green time
        sim_step: (double) time period of simulation step in seconds
        '''
        self.GreenTimer += sim_step

    def change2red(self):
        self.SG.SetAttValue('SigState', 1)
        self.GreenTimer = 0
    
    def update_rate(self, rate):
        '''
        update the signal period according to ramp metering rate
        '''
        self.redTime = 3600 / rate - self.greenTime

    def meter_step(self, sim_step):
        '''
        update the meter states for one simulation step
        '''
        if self.get_state() == 'RED':
            self.red_increment(sim_step)
            if self.RedTimer >= self.redTime:
                self.change2green()
        else:
            self.green_increment(sim_step)
            if self.GreenTimer >= self.greenTime:
                self.change2red()

